package cz.uvn.orthopedy.client.ui.controller;

import java.util.Date;
import java.util.Set;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import cz.uvn.orthopedy.client.ApplicationController;
import cz.uvn.orthopedy.client.entity.Hall;
import cz.uvn.orthopedy.client.entity.JournalEntry;
import cz.uvn.orthopedy.client.entity.Schedule;
import cz.uvn.orthopedy.client.entity.ScheduleEntry;
import cz.uvn.orthopedy.client.ui.editor.JournalEntryEditor;
import cz.uvn.orthopedy.client.ui.editor.ScheduleEntryEditor;

public class JournalController implements PanelController, ValueChangeHandler<Date> {

	private ApplicationController controller;
	
	private VerticalPanel journalPanel;
	private VerticalPanel tablePanel;
	private FlexTable table;
	
	private Button todayButton;
	private Button nextDayButton;
	private Button previousDayButton;
	private Button nextWeekButton;
	private Button previousWeekButton;
	private Label dateLabel;

	private Button createEntryButton;

	public JournalController(ApplicationController controller) {
		this.controller = controller;
		initUI();
	}

	private void initUI() {
		journalPanel = new VerticalPanel();
		journalPanel.setSpacing(2);
		journalPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
		journalPanel.add(createHeaderPanel());
		
		DecoratorPanel decoratorPanel = new DecoratorPanel();
		tablePanel = new VerticalPanel();
		tablePanel.setVerticalAlignment(VerticalPanel.ALIGN_TOP);
		tablePanel.setHorizontalAlignment(VerticalPanel.ALIGN_LEFT);
		decoratorPanel.add(tablePanel);
		
		journalPanel.add(decoratorPanel);

		journalPanel.add(createToolPanel());
		
		controller.getDatePicker().addValueChangeHandler(this);
	}
	
	private Widget createHeaderPanel() {
		FlexTable headerPanel = new FlexTable();
		headerPanel.setStyleName("headerPanel");

		dateLabel = new Label();
		dateLabel.setText(DateTimeFormat.getFormat(PredefinedFormat.DATE_LONG).format(new Date()));
		dateLabel.setStyleName("dateLabel");
		
		todayButton = new Button();
		todayButton.setStyleName("todayButton");
		todayButton.setText("Today");
		todayButton.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				Date d = new Date();
				controller.getDatePicker().setCurrentMonth(d);
				controller.getDatePicker().setValue(d, true);
			}
		});
		
		previousWeekButton = new Button();
		previousWeekButton.setStyleName("previousButton");
		previousWeekButton.setHTML("&laquo;");
		previousWeekButton.addClickHandler(new ClickHandler(){
			@SuppressWarnings("deprecation")
			@Override
			public void onClick(ClickEvent event) {
				Date d = controller.getDatePicker().getValue();
				d.setDate(d.getDate() - 7);
				controller.getDatePicker().setCurrentMonth(d);
				controller.getDatePicker().setValue(d, true);
			}
		});

		previousDayButton = new Button();
		previousDayButton.setStyleName("previousButton");
		previousDayButton.setHTML("&lt;");
		previousDayButton.addClickHandler(new ClickHandler(){
			@SuppressWarnings("deprecation")
			@Override
			public void onClick(ClickEvent event) {
				Date d = controller.getDatePicker().getValue();
				d.setDate(d.getDate() - 1);
				controller.getDatePicker().setCurrentMonth(d);
				controller.getDatePicker().setValue(d, true);
			}
		});

		nextDayButton = new Button();
		nextDayButton.setStyleName("nextButton");
		nextDayButton.setHTML("&gt;");
		nextDayButton.addClickHandler(new ClickHandler(){
			@SuppressWarnings("deprecation")
			@Override
			public void onClick(ClickEvent event) {
				Date d = controller.getDatePicker().getValue();
				d.setDate(d.getDate() + 1);
				controller.getDatePicker().setCurrentMonth(d);
				controller.getDatePicker().setValue(d, true);
			}
		});
		
		nextWeekButton = new Button();
		nextWeekButton.setStyleName("nextButton");
		nextWeekButton.setHTML("&raquo;");
		nextWeekButton.addClickHandler(new ClickHandler(){
			@SuppressWarnings("deprecation")
			@Override
			public void onClick(ClickEvent event) {
				Date d = controller.getDatePicker().getValue();
				d.setDate(d.getDate() + 7);
				controller.getDatePicker().setCurrentMonth(d);
				controller.getDatePicker().setValue(d, true);
			}
		});

		headerPanel.setWidget(0, 0, todayButton);
		headerPanel.setWidget(0, 1, previousWeekButton);
		headerPanel.setWidget(0, 2, previousDayButton);
		headerPanel.setWidget(0, 3, dateLabel);
		headerPanel.setWidget(0, 4, nextDayButton);
		headerPanel.setWidget(0, 5, nextWeekButton);
		headerPanel.setHTML(0, 6, "&nbsp;");
		
		headerPanel.getCellFormatter().setWidth(0, 0, "50%");
		headerPanel.getCellFormatter().setWidth(0, 7, "50%");
		
		headerPanel.setWidth("100%");
		headerPanel.setCellPadding(0);
		headerPanel.setCellSpacing(0);
		
		return headerPanel;
	}
	
	private Widget createToolPanel() {
		HorizontalPanel toolBar = new HorizontalPanel();
		toolBar.setWidth("100%");
		toolBar.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
		
		createEntryButton = new Button("Create Entry...");
		createEntryButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				showEditDialog(null);
			}
		});
		toolBar.add(createEntryButton);
		
		return toolBar;
	}

	@Override
	public Panel getView() {
		return journalPanel;
	}

	@Override
	public void refresh() {
		displayJournal();
	}
	
	private void displayJournal() {
		JournalEntry[] entries = controller.getEntries();
		Schedule schedule = controller.getSchedule();

		if (table != null) {
			table.removeFromParent();
		}
		table = new FlexTable();
		table.addStyleName("journalTable");
		tablePanel.add(table);

		int day = controller.getDatePicker().getValue().getDay();
        Set<Hall> halls = schedule.getHalls(day);
		int col = 0;
        int row = 0;
        // Header with Halls
		for (Hall hall : halls) {
	        table.setWidget(row, col++, new Label(hall.toString()));
		}
		table.getRowFormatter().addStyleName(0, "tableHeader");
   
		col = 0;
		for (Hall hall : halls) {
	        // Entries
//	        for (JournalEntry entry : entries) {
//	        	if (entry.getHallID() == hall.getId()) {
//	    			table.setWidget(++row, col, new JournalEntryPanel(controller, entry));
//	        	}
//	        }
			row = 1;
	        for (ScheduleEntry entry : schedule.getEntries(hall.getId(), day)) {
	        	table.setWidget(++row, col, new ScheduleEntryEditor(controller, entry));
	        }
	        col++;
		}
	}

	private void showEditDialog(final JournalEntry entry) {
		JournalEntryEditor journalEntryEditor = new JournalEntryEditor(entry, controller);
		journalEntryEditor.center();
	}

	@Override
	public void onValueChange(ValueChangeEvent<Date> date) {
		dateLabel.setText(DateTimeFormat.getFormat(PredefinedFormat.DATE_LONG).format(date.getValue()));
		controller.showJournal(true);
	}
}
